package com.totoro.tyrank.utils;

import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class NBTUtil {
    // 缓存反射方法
    private static final Map<String, Method> REFLECT_METHODS = new HashMap<>();
    // 单独缓存构造器（解决类型不匹配问题）
    private static final Map<String, Constructor<?>> REFLECT_CONSTRUCTORS = new HashMap<>();

    private static final String NMS_PREFIX;
    private static final String CRAFT_PREFIX;

    static {
        String serverVersion = getServerVersion();
        NMS_PREFIX = "net.minecraft.server." + serverVersion + ".";
        CRAFT_PREFIX = "org.bukkit.craftbukkit." + serverVersion + ".";

        try {
            // 加载CraftItemStack的方法
            Class<?> craftItemStackClass = Class.forName(CRAFT_PREFIX + "inventory.CraftItemStack");
            REFLECT_METHODS.put("asNMSCopy", craftItemStackClass.getMethod("asNMSCopy", ItemStack.class));
            REFLECT_METHODS.put("asBukkitCopy", craftItemStackClass.getMethod("asBukkitCopy", Class.forName(NMS_PREFIX + "ItemStack")));

            // 加载NMS ItemStack的方法
            Class<?> nmsItemStackClass = Class.forName(NMS_PREFIX + "ItemStack");
            REFLECT_METHODS.put("hasTag", nmsItemStackClass.getMethod("hasTag"));
            REFLECT_METHODS.put("getTag", nmsItemStackClass.getMethod("getTag"));
            REFLECT_METHODS.put("setTag", nmsItemStackClass.getMethod("setTag", Class.forName(NMS_PREFIX + "NBTTagCompound")));

            // 加载NBTTagCompound的方法和构造器
            Class<?> nbtClass = Class.forName(NMS_PREFIX + "NBTTagCompound");
            REFLECT_METHODS.put("setString", nbtClass.getMethod("setString", String.class, String.class));
            REFLECT_METHODS.put("hasKey", nbtClass.getMethod("hasKey", String.class));
            REFLECT_METHODS.put("getString", nbtClass.getMethod("getString", String.class));
            // 关键修复：用专门的构造器缓存存储Constructor对象
            REFLECT_CONSTRUCTORS.put("nbtConstructor", nbtClass.getConstructor());

        } catch (Exception e) {
            throw new RuntimeException("初始化NBT工具类失败", e);
        }
    }

    private static String getServerVersion() {
        String packageName = org.bukkit.Bukkit.getServer().getClass().getPackage().getName();
        return packageName.substring(packageName.lastIndexOf('.') + 1);
    }

    public static ItemStack addNBT(ItemStack item, String key, String value) {
        if (item == null || item.getType() == Material.AIR) {
            return item;
        }

        try {
            Object nmsItem = REFLECT_METHODS.get("asNMSCopy").invoke(null, item);
            boolean hasTag = (boolean) REFLECT_METHODS.get("hasTag").invoke(nmsItem);
            Object nbt = hasTag ? REFLECT_METHODS.get("getTag").invoke(nmsItem) :
                    REFLECT_CONSTRUCTORS.get("nbtConstructor").newInstance();

            REFLECT_METHODS.get("setString").invoke(nbt, key, value);
            REFLECT_METHODS.get("setTag").invoke(nmsItem, nbt);
            return (ItemStack) REFLECT_METHODS.get("asBukkitCopy").invoke(null, nmsItem);

        } catch (Exception e) {
            e.printStackTrace();
            return item;
        }
    }

    public static String getNBT(ItemStack item, String key) {
        if (item == null || item.getType() == Material.AIR) {
            return null;
        }

        try {
            Object nmsItem = REFLECT_METHODS.get("asNMSCopy").invoke(null, item);
            if (!(boolean) REFLECT_METHODS.get("hasTag").invoke(nmsItem)) {
                return null;
            }

            Object nbt = REFLECT_METHODS.get("getTag").invoke(nmsItem);
            if (!(boolean) REFLECT_METHODS.get("hasKey").invoke(nbt, key)) {
                return null;
            }

            return (String) REFLECT_METHODS.get("getString").invoke(nbt, key);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
